package com.viu.technology.controller;

import com.alibaba.fastjson.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/api/advance")
public class AdvanceController {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 接口限流，该代码作为演示使用，项目中应该在过滤器或拦截器中使用
     * @return
     */
    @GetMapping("/currentLimiting")
    public String addCcurrentLimiting() {

        List<Object> results =redisTemplate.executePipelined(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
                StringRedisConnection connection = (StringRedisConnection)redisConnection;
                //获取当前毫秒数
                Long time = System.currentTimeMillis();
                //开启事务
                connection.multi();
                //添加一条数据到zset中，score为当前毫秒数，value为唯一值(不重要,只要不重复即可)
                connection.zAdd("currentLimit:test", time, String.valueOf(System.nanoTime()));
                //保留当前时间前10秒的数据，即清空该次请求10秒钟前的所有请求记录
                connection.zRemRangeByScore("currentLimit:test", 0, time-10*1000);
                //统计10秒内请求量
                connection.zCard("currentLimit:test");
                connection.exec();

                return null;
            }
        });
        JSONArray jsonArray = JSONArray.parseArray(String.valueOf(results.get(0)));
        int time =jsonArray.getIntValue(2);
        //如果10秒内请求量大于10则提示系统繁忙
        if (time>10) {
            return "系统繁忙";
        }
        return "success";
    }

}
